function LiveSessionCallLogger() {
    this.cache = "";
	this.filename = "";
}

LiveSessionCallLogger.prototype.start = function(metadata) {
	this.startMilliseconds = Date.now();
	this.startDate = new Date();
	// Create a file name like 20071125101910.klf
	var year = this.startDate.getFullYear() + "";
	var month = this.startDate.getMonth() + 1 < 10 ? "0" + (this.startDate.getMonth() + 1) : "" + (this.startDate.getMonth() + 1);
	var day = this.startDate.getDate() < 10 ? "0" + this.startDate.getDate() : "" + this.startDate.getDay();
	var hour = this.startDate.getHours() < 10 ? "0" + this.startDate.getHours() : "" + this.startDate.getHours();
	var minute = this.startDate.getMinutes() < 10 ? "0" + this.startDate.getMinutes() : "" + this.startDate.getMinutes();
	var second = this.startDate.getSeconds() < 10 ? "0" + this.startDate.getSeconds() : "" + this.startDate.getSeconds();
	this.filename = year + month + day + hour + minute + second + ".klf";
	// Create file
	this.logFile = new File("/liveSessionLogs/" + this.filename)
	this.logFile.open("utf8", "write");
	this.logFile.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
	this.logFile.write("<seminar>\n");
	if(metadata != undefined) {
		this.logFile.write("\t<metadata>\n" + this.objectToXMLString(metadata,2) + "\t</metadata>\n");
	}
	this.logFile.write("\t<calls>\n");
}

LiveSessionCallLogger.prototype.logCall = function (soName, funcName, parameters) {
	callMilliseconds = Date.now() - this.startMilliseconds;
	if(this.logFile == undefined) {
    this.cache += "\t\t<call time='" + callMilliseconds + "' so='" + soName + "' function='" + funcName + "'>\n\t\t\t<parameters>\n" + this.objectToXMLString(parameters,4) + "\t\t\t</parameters>\n\t\t</call>\n";
		return;
	} else if (this.cache != "") {
    this.logFile.write(this.cache);
    this.cache = "";
	}
	this.logFile.write("\t\t<call time='" + callMilliseconds + "' so='" + soName + "' function='" + funcName + "'>\n\t\t\t<parameters>\n" + this.objectToXMLString(parameters,4) + "\t\t\t</parameters>\n\t\t</call>\n");
}

LiveSessionCallLogger.prototype.finishAndSave = function() {
	trace("LiveSessionCallLogger: Saving log and closing.");
	if(this.logFile == undefined) {
		return;
	}
	this.logFile.write("\t</calls>\n</seminar>");
	this.logFile.flush();
	this.logFile.close();
}

LiveSessionCallLogger.prototype.nCharacter = function(character,n){
	var str="";
	for(var i=0;i<n;i++) str+=character;
	return str;
}

LiveSessionCallLogger.prototype.objectToXMLString = function(obj,tabCount) {
	var str=this.nCharacter("\t",tabCount);
	if(tabCount>15) return (str+" ###Recursion exceeds max limit, possibly a loop\n");
	switch(typeof(obj)){
		case "string":
			str+="<string>"+obj+"</string>\n";
		break;
		case "number":
			str+="<number>"+obj+"</number>\n";
		break;
		case "boolean":
			str+="<boolean>"+obj+"</boolean>\n";
		break;
		case "object":
			if(obj==null){
				str+="<null />\n";
			}
			else if(obj==undefined){
				str+="<undefined />\n";
			}
			else if(obj instanceof Array){
				// this is an array
				str+="<array>\n";
				for(var j=0;j<obj.length;j++){
					str+=this.nCharacter("\t",tabCount+1);
					str+="<"+j+">\n";
					str+=this.objectToXMLString(obj[j],tabCount+2);
					str+=this.nCharacter("\t",tabCount+1);
					str+="</"+j+">\n";
				}
				str+=this.nCharacter("\t",tabCount);
				str+="</array>\n";
			}
			else{
				// this is an object
				str+="<object>\n";
				for(var key in obj){
					str+=this.nCharacter("\t",tabCount+1);
					str+="<"+key+">\n";
					str+=this.objectToXMLString(obj[key],tabCount+2);
					str+=this.nCharacter("\t",tabCount+1);
					str+="</"+key+">\n";
				}
				str+=this.nCharacter("\t",tabCount);
				str+="</object>\n";
			}
			
		break;
		case "array":
			// does not return array;
		break;
		default:
			str+=" #UKNOWN OBJECT TYPE ("+typeof(obj)+")\n";
		break;
	}
	return str;
}